<?php

namespace Desktopd\PlatformTools;


class ObjectTools {
    protected $object;
    protected $class;
    
    
    public function __construct ($object) {
        if (!is_object($object)) {
            throw new \BadMethodCallException("Not an object");
        }
        
        $this->object = $object;
        $this->class = get_class($object);
    }
    
    public function propertyIsSet ($name) {
        return isset($this->object->{$name});
    }
    
    public function unsetProperty ($name) {
        unset($this->object->{$name});
    }
    
    public function getProperty ($name) {
        return $this->propertyIsSet($name) ? $this->object->{$name} : null;
    }
    
    // XXX: produces a PHP error if a non-public property name is given
    // Fixed?
    public function setProperty ($name, $value) {
        try {
            $reflection = new \ReflectionProperty($this->class, $name);
            if (!$reflection->isPublic()) {
                try {
                    $__set = new \ReflectionMethod($this->class, "__set");
                } catch (\ReflectionException $e) {
                    // not overloaded
                    throw new \RuntimeException("Trying to write to a non-public non-overloaded property");
                }
            }
        } catch (\ReflectionException $e) {
            // ignore
        }
        
        return $this->object->{$name} = $value;
    }
    
    public function callProperty ($name, array $arguments = array()) {
        $property = $this->getProperty($name);
        if (!is_callable($property)) {
            throw new \RuntimeException("No such method on the object({$this->class}): $name");
        }
        
        return (new \ReflectionFunction($property))->invokeArgs($arguments);
    }
    
    public function callMethod ($name, array $arguments = array()) {
        $method = array($this->object, $name);
        if (!is_callable($method)) {
            throw new \RuntimeException("No such method on the object({$this->class}): $name");
        }
        
        return (new \ReflectionFunction($method))->invokeArgs($arguments);
    }
}


// vim: ts=4 et ai

